<?php
//=======================================
//###################################
// Kayako Web Solutions
//
// Source Copyright 2001-2004 Kayako Infotech Ltd.
// Unauthorized reproduction is not allowed
// License Number: $%LICENSE%$
// $Author: vshoor $ ($Date: 2007/07/25 06:54:39 $)
// $RCSfile: functions_parsercore.php,v $ : $Revision: 1.49 $ 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###################################
//=======================================

if (!defined("INSWIFT")) {
	trigger_error("Unable to process $PHP_SELF", E_USER_ERROR);
}

/**
* Debug Parser Function
*/
function parserDebug($debugstr)
{
	global $_SWIFT;

	if (!$_SWIFT["clidebug"])
	{
		return false;
	}

	$_SWIFT["debugdata"] .= $debugstr."\n";

	$fp = fopen("./files/".$_SWIFT["dbgfilename"], "a+");
	fwrite($fp, "[". edate($_SWIFT["settings"]["dt_datetimeformat"], time()) ."] ".$debugstr.SWIFT_CRLF);
	fclose($fp);

	return true;
}

/**
* Parses the Mime Data into a proper structure
*/
function parseRawMimeData($mimedata)
{
	global $_SWIFT, $tickets, $settings, $dbCore, $template;

	parserDebug("PARSER: Initiating MIME Classes");
	$mimeparser = new MimeParser();

	// Lets make sure the data has proper Line Feeds
	$mimedata = preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $mimedata);

	parserDebug("PARSER: Decoding Mail");
	$rawstructure = $mimeparser->decodeMail($mimedata);

	parserDebug("PARSER: Mail Decoded");
	// ======= LOAD THE PARSER RULES =======
	loadParserRules();

	$_email = array();
	$_email["mimedata"] = $mimedata;
	unset($mimedata);

	// Load default values into structure
	$_email["fromName"] = trim($rawstructure->fromName);
	$_email["fromEmail"] = trim($rawstructure->fromEmail);
	$_email["fromNameRule"] = trim($rawstructure->fromName);
	$_email["fromEmailRule"] = trim($rawstructure->fromEmail);

	$_email["toName"] = trim($rawstructure->toName);
	$_email["toEmail"] = trim($rawstructure->toEmail);

	$_email["replytoName"] = trim($rawstructure->replytoName);
	$_email["replytoEmail"] = trim($rawstructure->replytoEmail);

	if ($_SWIFT["settings"]["pr_parsereplyto"] == 1 && trim($_email["replytoEmail"]) != "")
	{
		$_email["fromEmail"] = $_email["replytoEmail"];
		if (trim($_email["replytoName"]) != "")
		{
			$_email["fromName"] = $_email["replytoName"];
		}
	}

	$_email["subject"] = trim($rawstructure->subject);
	$_email["returnAddress"] = trim($rawstructure->returnAddress);
	$_email["returnAddressName"] = trim($rawstructure->returnAddressName);
	$_email["returnAddressEmail"] = trim($rawstructure->returnAddressEmail);
	$_email["recipients"] = $rawstructure->recipientAddresses;

	$_email["text"] = $rawstructure->text;
	$_email["textSize"] = $rawstructure->textSize;
	$_email["html"] = $rawstructure->html;
	$_email["htmlSize"] = $rawstructure->htmlSize;
	$_email["inReplyTo"] = $rawstructure->inReplyTo;

	// Is From Name empty?
	if (trim($_email["fromName"]) == "")
	{
		$_email["fromName"] = $_email["fromEmail"];
	}

	// Is To Name Empty?
	if (trim($_email["toName"]) == "")
	{
		$_email["toName"] = $_email["toEmail"];
	}

	// Subject empty?
	if (trim($_email["subject"]) == "")
	{
		$_email["subject"] = $_SWIFT["language"]["nosubject"];
	}
	
	if ($_SWIFT["clidebug"])
	{
		ob_start();
		print_r($rawstructure);
		$_debugcontents = ob_get_contents();
		ob_end_clean();
		parserDebug("STRUCTURE: ".$_debugcontents);
		unset($_debugcontents);
	}

	if ($_SWIFT["clifileload"])
	{
//		echo $_SWIFT["debugdata"]."\n";

//		print_r($rawstructure);
//		exit;
	}
	
	if ($_SWIFT["clidebug"])
	{
		parserDebug("MIME: ".$_email["mimedata"]);
	}

	parserDebug("PARSER: Mail Decoded. From Name: ". $_email["fromName"] .", From Email: ". $_email["fromEmail"] .", Subject: ". $_email["subject"] .", To Email: ". $_email["toEmail"] .", Text Size: ". $_email["textSize"] .", HTML Size: ".$_email["htmlSize"]);

	// Process Content-Type
	if (!empty($rawstructure->headers["content-type"]))
	{
		$_contenttype = processContentType($rawstructure->headers["content-type"]);
		$_email["charset"] = $_contenttype["charset"];
	}
	$_email["transferencoding"] = $rawstructure->headers["content-transfer-encoding"];
	parserDebug("PARSER: Processed Charset (". $_email["charset"] .") and Transfer Encoding (". $_email["transferencoding"] .")");

	// Process Attachments
	$_email["attachments"] = $_email["attachmentNames"] = $_email["attachmentSizes"] = array();
	$attachments = &$rawstructure->attachments;
	$_attachmentcache = $_SWIFT["attachmenttypescache"];
	$_checkattach = false;
	if (_is_array($_attachmentcache))
	{
		$_checkattach = true;
	}

	$totalsize = $_email["totalAttachmentSize"] = 0;
	for ($ii=0; $ii<count($attachments); $ii++) {
		if ($_SWIFT["settings"]["tickets_resattachments"] == 1 && $_checkattach == true)
		{
			$ext = getFileExtension($attachments[$ii]["filename"]);
			if (!in_array($ext, $_attachmentcache))
			{
				// Continue because this attachment isnt in our allowed list
				continue;
			}
		}
		$itemsize = strlen($attachments[$ii]["data"]);
		$totalsize += $itemsize;
		$_email["attachments"][$ii]["contents"] = $attachments[$ii]["data"];
		$_email["attachments"][$ii]["filesize"] = $itemsize;
		$_email["attachments"][$ii]["filename"] = $attachments[$ii]["filename"];
		$_email["attachments"][$ii]["contenttype"] = $attachments[$ii]["contenttype"];
		$_email["attachmentNames"][] = $attachments[$ii]["filename"];
		$_email["attachmentSizes"][] = $itemsize;
		$_email["totalAttachmentSize"] += $itemsize;

		$attachments[$ii] = 0; // Free Memory
	}
	parserDebug("PARSER: Processed Attachments. Total Attachments in Email: ".count($_email["attachments"]).", Total Attachment Size: ".formattedSize($totalsize));

	// Unset all data heavy variables to free up some memory
	unset($attachments);
	unset($rawstructure);

	if (count($_email["recipients"]) <= 0)
	{
		parserDebug("ERROR: No Recipients Found.. Shutting Down!");
		doParserLog(PARSER_FAILURE, 0, 0, 0, $_email["subject"], $_email["fromEmail"], $_email["toEmail"], $_SWIFT["language"]["errnorecipients"], 0, LOG_TICKET, $_email);
		return false;
	}

	if (trim($_email["fromEmail"]) == "")
	{
		parserDebug("ERROR: No From Email Found.. Shutting Down!");
		doParserLog(PARSER_FAILURE, 0, 0, 0, $_email["subject"], "", $_email["toEmail"], $_SWIFT["language"]["errnofromemail"], 0, LOG_TICKET, $_email);
		return false;
	}

	// Get the Email Queue data for this email
	$_queuedata = getEmailQueueData($_email["recipients"], $_email);
	if (!$_queuedata)
	{
		parserDebug("ERROR: No Destination Email Found.. Shutting Down!");
		doParserLog(PARSER_FAILURE, 0, 0, 0, $_email["subject"], $_email["fromEmail"], $_email["toEmail"], $_SWIFT["language"]["errnoqueues"], 0, LOG_TICKET, $_email);
		return;
	}

	// Set default values from Email Queue
	$_email["queue"] = $_queuedata;
	unset($_queuedata);

	$template->setGroup($_email["queue"]["tgroupid"]);

	// Process Parser Bans
	if (isParserEmailBanned($_email["fromEmail"]))
	{
		// This email is banned!
		parserDebug("ERROR: Email is Banned.. Shutting Down!");
		doParserLog(PARSER_FAILURE, 0, 0, 0, $_email["subject"], "", $_email["toEmail"], $_SWIFT["language"]["erremailbanned"], 0, LOG_TICKET, $_email);
		return false;
	}

	// Check for ticket id or mask id in subject, if found check for existance of ticket
	$ticketiddata = array();
	$ticketiddata = parseTicketID($_email["subject"]);

	$_email["staffmsgidcheck"] = false;
	if ($_SWIFT["settings"]["t_stmsgid"] != 1)
	{
		$_email["staffmsgidcheck"] = true; // Always true if option is disabled
	}

	if (substr($_email["inReplyTo"], 0, 6) == "staff." && $_SWIFT["settings"]["t_stmsgid"] == 1)
	{
		// Need to compare message id..
		$realmsgid = substr($_email["inReplyTo"], 6);
		$_email["inReplyTo"] = $realmsgid;
		$_msgticketid = getTicketIDFromMessageID($_email["inReplyTo"]);
		$_email["staffmsgidticketid"] = $_msgticketid;
	}

	if (empty($ticketiddata["mask"]) && empty($ticketiddata["id"]))
	{
		// It seems that the ticket id isnt in subject of this mail.. do we have an inreplyto set?
		if (!empty($_email["inReplyTo"]))
		{
			// Yup! Lets see if we can lookup ticket id
			$_msgticketid = getTicketIDFromMessageID($_email["inReplyTo"]);
			if ($_msgticketid) // We found a ticket through Message-ID! It Works! It Works!
			{
				$ticketiddata["id"] = $_msgticketid;
				parserDebug("LOOKUP: Found Ticket Using Message ID: ".$_email["inReplyTo"]);
				
			}
		}

		// Ok Mate.. now this calls for some hardcore measures.. because we couldnt even find the ticket from the message-id!
		if (empty($ticketiddata["id"]))
		{
			// We try to look it up in the entire mail
			$ticketiddata = parseTicketID($_email["mimedata"]); // try to look it up in the mail body
			parserDebug("LOOKUP: Found Ticket ID In Body!");
		}

		// Its Still Empty?!?!?! How in this world can this be possible.. we only proceed if the subject has :, otherwise its most probably a new ticket..
		if (empty($ticketiddata["id"]) && empty($ticketiddata["mask"]) && stristr($_email["subject"], ":"))
		{
			$parsedSubject = trim(substr(stristr($_email["subject"], ":"),1));
			// See if we can look it up using similar subject..
			$_usingsubject = $dbCore->queryFetch("SELECT `ticketid` FROM `". TABLE_PREFIX ."tickets` WHERE `email` = '". $dbCore->escape($_email["fromEmail"]) ."' AND `subject` = '". $dbCore->escape(substr($parsedSubject,0,200)) ."' ORDER BY `ticketid` DESC LIMIT 1;");
			if (!empty($_usingsubject["ticketid"]))
			{
				$ticketiddata["id"] = $_usingsubject["ticketid"];
				parserDebug("LOOKUP: Found Ticket ID Using Mail Subject: ".$_email["subject"]);
			}
		}

		// Ok.. I give up.. this has to be a new ticket..
	}
	if (!empty($ticketiddata["mask"]))
	{
		$_ticketmask = $ticketiddata["mask"];
		$_ticketid = getTicketIDFromMask($ticketiddata["mask"]);
	} else if (!empty($ticketiddata["id"])) {
		$_ticketid = $ticketiddata["id"];
	} else {
		$_ticketid = false;
	}
	if ($ticketiddata["isthirdparty"] == true)
	{
		$_email["isthirdparty"] = true;
	}
	if ($ticketiddata["isalert"] == true)
	{
		$_email["isalert"] = true;
	}

	// Cleanup the subject
	$_email["subject"] = cleanupSubject($_email["subject"]);

	// Check for merged status, this step will only be executed if there was a ticket id or mask in subject and we were unable to find it in the database
	if (!$_ticketid && (trim($ticketiddata["mask"]) != "" || trim($ticketiddata["id"]) != ""))
	{
		if (trim($ticketiddata["mask"]) != "")
		{
			// Is this ticket merged?
			if ($mergedticketid = getMergedStatusFromMask($ticketidata["mask"]))
			{
				$_ticketid = $mergedticketid;
			}
		} else if (trim($ticketiddata["id"]) != "") {
			// Is this ticket merged? (yeah again another check)
			if ($mergedticketid = getMergedStatusFromID($ticketiddata["id"]))
			{
				$_ticketid = $mergedticketid;
			}
		}
	}

	// Now we should know whether this email belongs to a ticket or not. If there is a ticketid set, try to load the given ticket.
	$_ticket = false;
	$sendautoresponder = true;

	// Before we proceed, we need to see if the email is from the queue email itself
	if ($_SWIFT["queuecache"]["p"][$_email["fromEmail"]] == 1)
	{
		// We never send the autoresponder if the email belongs to the queue.. never, ever.. mail loops are evil
		$sendautoresponder = false;
	}

	if ($_ticketid)
	{
		$_ticket =& new TicketMain($_ticketid);
		$_SWIFT["ticketobj"] =& $_ticket;
	}
	// The final reply/ticket check, by now we would have tried every freaking thing out there to see if this email belongs to an existing ticket
	if (!empty($_ticket->ticket["ticketid"]))
	{
		// We found a ticket to which this email belongs, so we fill up the data
		$_email["isticketreply"] = true;
		$_email["ticketid"] = $_ticketid;
		$_email["dispatchticketid"] = iif($_SWIFT["settings"]["t_eticketid"]=="seq",$_ticket->ticket["ticketid"], $_ticket->ticket["ticketmaskid"]);
		$_email["dispatchsubject"] = $_ticket->getEmailSubject(SUBJECT_USER);
	} else {
		// Failed to load the ticket..
		$_email["isticketreply"] = false;
	}

	parserDebug("PARSER: ".iif($_email["isticketreply"]==true, "Is Ticket Reply for ".$_email["ticketid"], "Is a New Ticket"));

	// This is where we parse out the original email content and decide which one to store, text or html
	if ($_SWIFT["settings"]["pr_contentpriority"] == "text")
	{
		// Text is empty but we do have HTML content in there. This will happen in very rare cases
		if (trim($_email["text"]) == "")
		{
			$_email["ishtml"] = true;
			$emailcontent = iif($_SWIFT["settings"]["pr_stripscript"]==1, stripScriptTag($_email["html"]), $_email["html"]);
		} else {
			$_email["ishtml"] = false;
			$emailcontent = $_email["text"];
		}
	} else if ($_SWIFT["settings"]["pr_contentpriority"] == "html") {
		if (trim($_email["html"]) == "")
		{
			$_email["ishtml"] = false;
			$emailcontent = $_email["text"];
		} else {
			$_email["ishtml"] = true;
			$emailcontent = iif($_SWIFT["settings"]["pr_stripscript"]==1, stripScriptTag($_email["html"]), $_email["html"]);
		}
	}

	// Process the final content by splitting the original content using break lines.
	if ($_email["isticketreply"] == true)
	{
		$_email["finalContent"] = processBreakLines($emailcontent);
	} else {
		$_email["finalContent"] = $emailcontent;
	}
	parserDebug("PARSER: Final Content Is: ".$_email["finalContent"]);

	// ======= REWRITTEN FLOOD PROTECTION v3.00.80 BUILD =======

	// Check for Flood Protection
	$_email["floodprotection"] = false;
	if (checkFloodProtection($_email["fromEmail"], md5($_email["subject"])) == true)
	{
		parserDebug("WARNING: Flood Protection Triggered");
		$_email["floodprotection"] = true;
		if ($_SWIFT["settings"]["t_fnoadd"] == 1)
		{
			parserDebug("ERROR: Flood Protection Option for Rejecting Emails Enabled, Shutting Down...");
			doParserLog(PARSER_FAILURE, $_ticketid, $_ticketmask, $_email["queue"]["emailqueueid"], $_email["subject"], $_email["fromEmail"], $_email["toEmail"], $_SWIFT["language"]["errfloodprotection"], 0, LOG_TICKET, $_email);
			return false;
		} else if ($_SWIFT["settings"]["t_fresponder"] == 1) {
			$sendautoresponder = false;
		}
	}

	// Insert the entry into flood protection hash
	insertFloodProtectionEntry($_email["fromEmail"], $_email["subject"]);

	// Check for staff reply
	$_email["isstaffreply"] = false;
	if ($_SWIFT["settings"]["t_pstaffreply"] == 1 && $_email["isticketreply"] == true && $_email["isthirdparty"] != true && $_email["isalert"] == true)
	{
		if (isStaffEmail($_email["fromEmail"]))
		{
			parserDebug("PARSER: Reply is by Staff");
			if ((!$_email["staffmsgidcheck"] && $_email["staffmsgidticketid"] == $_ticket->ticket["ticketid"] && !empty($_email["staffmsgidticketid"])) || $_email["staffmsgidcheck"] == true)
			{
				parserDebug("PARSER: Staff MSGID Check is Success");
				$_email["isstaffreply"] = true;
			} else {
				parserDebug("PARSER: Staff MSGID Check is Failure");
			}
		}
	}

	// ======= RUN THE PARSER RULES =======
	$parserruleidlist = runParserRules($_email, $_ticket);

	executeParserRuleActions($parserruleidlist, RULE_PREPARSE, $_email, $_ticket);
	if ($_email["ignore"] == true)
	{
		return false;
	}

	if ($_email["noautoresponder"] == true)
	{
		parserDebug("PARSER: Not sending auto responder as it is disabled in queue");
		$sendautoresponder = false;
	} else {
			parserDebug("PARSER: Auto responder is enabled in queue");
	}

	if ($_email["noalertrules"] == true && is_object($_ticket))
	{
		$_ticket->noalertrules = true;
	}

	// Set the template group
	$template->setGroup($_email["queue"]["tgroupid"]);
	$template->loadLanguageSection("default", TEMPLATE_DB);
	$template->loadLanguageSection("ticketemails", TEMPLATE_DB);

	// Create a New Customer Reply
	if ($_email["isticketreply"] == true && $_email["isstaffreply"] == false)
	{

		$userid = getUserEmail($_email["fromEmail"]);
		if (!$userid) // Do we need to add the user to recipients?
		{
			$add = true;
			$isrecipient = false;
			$_recipients = $_ticket->getRecipients();
			if (is_array($_recipients))
			{
				foreach ($_recipients as $key=>$val)
				{
					if ($val["email"] == $_email["fromEmail"])
					{
						$isrecipient = true;
						$add = false;
					}
				}
			}

			if ($add == true)
			{
				$isrecipient = true;
				$_ticket->addRecipients(array($_email["fromEmail"]), RECIPIENT_CCUSER);
			}
		}
		$_ticket->resetSLATimeline();

		if ($_email["isthirdparty"] == true)
		{
			$posttype = POST_THIRDPARTY;
		} else if ($isrecipient == true) {
			$posttype = POST_RECIPIENT;
		} else {
			$posttype = POST_CLIENT;
		}

		// Create the Ticket Post
		$ticketpostresult = $_ticket->createTicketPost(false, $posttype, $userid, "0", $_email["fromName"], $_email["fromEmail"], "", $_email["subject"], $_email["finalContent"], $_email["ishtml"], true, $_email["attachments"]);
		$ticketpostid = $ticketpostresult[0];

		if (empty($_SWIFT["settings"]["t_cstatusupd"]))
		{
//			$_ticket->resetTemplateGroupStatus();
		}

		parserDebug("SUCCESS: Created Post: ".$ticketpostid);

		doParserLog(PARSER_SUCCESS, $_ticketid, $_ticketmask, $_email["queue"]["emailqueueid"], $_email["subject"], $_email["fromEmail"], $_email["toEmail"], sprintf(iif($_email["isthirdparty"]==true,$_SWIFT["language"]["sctcreatedreply"], $_SWIFT["language"]["scccreatedreply"]), $ticketpostid, $_email["dispatchticketid"]), 0, LOG_REPLY, $_email, $ticketpostid);

	// Create a New Staff Reply
	} else if ($_email["isticketreply"] == true && $_email["isstaffreply"] == true) {

		foreach ($_SWIFT["staffcache"] as $key=>$val)
		{
			if ($val["email"] == $_email["fromEmail"])
			{
				$_staffid = $val["staffid"];
				break;
			}
		}

		if ($_staffid)
		{
			// Create the Ticket Post for Staff
			$ticketpostid = $_ticket->createStaffReply($_staffid, $_email["fromName"], $_email["fromEmail"], $_email["subject"], $_email["finalContent"], true, $_email["queue"]["emailqueueid"], $_email["attachments"], "", false, "", false);

			// Reset status to default template group one..
			$_ticket->resetTemplateGroupStatus();

			parserDebug("SUCCESS: Created Staff Post: ".$ticketpostid);

			doParserLog(PARSER_SUCCESS, $_ticketid, $_ticketmask, $_email["queue"]["emailqueueid"], $_email["subject"], $_email["fromEmail"], $_email["toEmail"], sprintf($_SWIFT["language"]["scccreatedstaffreply"], $ticketpostid, $_email["dispatchticketid"]), 0, LOG_REPLY, $_email, $ticketpostid);
		}
	// Create a New Ticket
	} else {
		// Check to see if registration required is enabled for this queue
		$userid = getUserEmail($_email["fromEmail"]);
		if ($_email["queue"]["registrationrequired"] == 1 && !$userid && !isset($_SWIFT["queuecache"]["p"][$_email["fromEmail"]]))
		{
			// ======= BEGIN MAIL SEND CODE =======
			// Hard Coded Bounce Checks, No other way to work around this...
			if (!stristr($_email["fromEmail"], "MAILER-DAEMON") && !stristr($_email["subject"], "failure notice") && !stristr($_email["subject"], "Returned Mail"))
			{
				require_once ("./includes/functions_mail.php");

				$template->setGroup(iif(empty($_email["queue"]["tgroupid"]), 1, $_email["queue"]["tgroupid"]));
				$template->assign("ishtml", true);
				$_templateresulthtml = $template->displayTemplate("email_noregistration", TEMPLATE_DB);
				$template->assign("ishtml", false);
				$_templateresulttext = $template->displayTemplate("email_noregistration", TEMPLATE_DB);

				$mailObj = new SWIFT_Mail();

				$mailObj->setSubject($_SWIFT["language"]["regemailrejectsub"]);
				$mailObj->setData($_templateresulthtml, $_templateresulttext);

				$mailObj->sendMail($_email["fromEmail"], $_SWIFT["settings"]["general_returnemail"], $_SWIFT["settings"]["general_companyname"], false);
			}
			// ======= END MAIL SEND CODE =======

			// Check for the email in registered users table
			doParserLog(PARSER_FAILURE, $_ticketid, $_ticketmask, $_email["queue"]["emailqueueid"], $_email["subject"], $_email["fromEmail"], $_email["toEmail"], sprintf($_SWIFT["language"]["errusernotreg"], htmlspecialchars($_email["fromEmail"])), 0, LOG_TICKET, $_email);
			return false;
		}

		// Register the user.
		if (!$userid)
		{
			$emailtgroup = $_email["queue"]["tgroupid"];
			$usergroupid = $_SWIFT["tgroupcache"][$emailtgroup]["regusergroupid"];
			if (empty($usergroupid))
			{
				$usergroupid = 2;
			}
			$_loginapi = LOGINAPI_DEFAULT;
			if (!empty($_SWIFT["tgroupcache"][$emailtgroup]["loginapi_moduleid"]))
			{
				$_loginapi = $_SWIFT["tgroupcache"][$emailtgroup]["loginapi_moduleid"];
			}
			$userid = insertUser(iif($_SWIFT["settings"]["u_enablesveri"]==1, false, true), $_email["fromEmail"], substr(buildHash(),0, 8), $usergroupid, $_loginapi, 0, $_email["fromName"], 0, 0, false, 1, true);
			parserDebug("SUCCESS: Created User: ".$userid);
		}

		if ($sendautoresponder)
		{
			$sendautoresponder = true;
		} else {
			$sendautoresponder = false;
		}

		$_ticketiddata = createTicket(POST_CLIENT, 0, $userid, $_email["fromName"], $_email["fromEmail"], $_email["subject"], $_email["finalContent"], iif($_email["ishtml"]==true, "1", "0"), $_email["queue"]["priorityid"], $_email["queue"]["ticketstatusid"], $_email["queue"]["departmentid"], $_email["queue"]["emailqueueid"], $_email["charset"], $_email["transferencoding"], $_email["queue"]["tgroupid"], $_email["attachments"], true, $sendautoresponder);

		parserDebug("SUCCESS: Created Ticket: ".$_ticketiddata[1]);

		doParserLog(PARSER_SUCCESS, $_ticketiddata[0], $_ticketiddata[1], $_email["queue"]["emailqueueid"], $_email["subject"], $_email["fromEmail"], $_email["toEmail"], sprintf($_SWIFT["language"]["scccreatedticket"], iif($_SWIFT["settings"]["t_eticketid"]=="seq",$_ticketiddata[0], $_ticketiddata[1])), 0, LOG_TICKET, $_email, $_ticketiddata[2]);
	}

	if (is_object($_SWIFT["ticketobj"]))
	{
		parserDebug("SUCCESS: Ticket Object is Valid");

		if (count($_email["recipients"]) > 1 && $_SWIFT["settings"]["t_autorecip"] == 1)
		{
			foreach($_email["recipients"] as $recipient)
			{
				if($recipient != $_email['fromEmail'] && $recipient != $_email['toEmail'] && $recipient != $_email["replytoEmail"] && !in_array($recipient,$_SWIFT["ticketobj"]->getRecipients()) && $_SWIFT["queuecache"]["p"][$recipient] != 1)
				{
					$_SWIFT["ticketobj"]->addRecipients(array($recipient),RECIPIENT_CCUSER);
				}
			}
		}
	} else {
		parserDebug("FAILURE: Ticket Object is Invalid");
	}

	executeParserRuleActions($parserruleidlist, RULE_POSTPARSE, $_email, $_SWIFT["ticketobj"]);

	return true;
}

/**
* Insert Flood Protection Entry
*/
function insertFloodProtectionEntry($email, $subject)
{
	global $dbCore;

	$dbCore->query("INSERT INTO `". TABLE_PREFIX ."floodhash` (`dateline`, `emailhash`, `subjecthash`) VALUES ('". DATENOW ."', '". $dbCore->escape(md5($email)) ."', '". $dbCore->escape(md5($subject)) ."');");

	parserDebug("NOTICE: Inserting Flood Protection Entry, EmailHash: ".md5($email).", SubjectHash: ".md5($subject));


	return true;
}

/**
* Create a parser log entry
*/
function doParserLog($status, $typeid, $ticketmaskid, $emailqueueid, $subject, $fromemail, $toemail, $description, $parsetimetaken, $responsetype, $_email, $ticketpostid=0)
{
	global $dbCore, $_SWIFT;

	if ($_SWIFT["settings"]["pr_enablelog"] != 1)
	{
		// return right here because logging is disabled
		return false;
	}

	if (empty($parsetimetaken))
	{
		$_SWIFT["endparser"] = fetchmicrotime();
		$parsetimetaken = $_SWIFT["endparser"]-$_SWIFT["startparser"];
	}

	$size = strlen($_email["mimedata"]);

	$dbCore->query("INSERT INTO `". TABLE_PREFIX ."parserlogs` (`typeid`, `ticketmaskid`, `dateline`, `emailqueueid`, `logtype`, `subject`, `fromemail`, `toemail`, `size`, `description`, `parsetimetaken`, `responsetype`, `ticketpostid`) VALUES ('". intval($typeid) ."', '". $dbCore->escape($ticketmaskid) ."', '". DATENOW ."', '". intval($emailqueueid) ."', '". $dbCore->escape(iif($status==PARSER_SUCCESS, "success", "failure")) ."', '". $dbCore->escape($subject) ."', '". $dbCore->escape($fromemail) ."', '". $dbCore->escape($toemail) ."', '". $dbCore->escape($size) ."', '". $dbCore->escape($description) ."', '". $dbCore->escape($parsetimetaken) ."', '". $dbCore->escape($responsetype)."', '". intval($ticketpostid) ."');");
	$parserlogid = $dbCore->lastInsertId();

	if (!$parserlogid)
	{
		return false;
	}


	// Check for max log size before proceeding..
	$size = $size/1024;
	$maxlogsizekb = intval($_SWIFT["settings"]["pr_maxlogsize"]);
	$maxlogsize = $maxlogsizekb*1024;

	parserDebug("VARIABLE: size: ".$size);
	parserDebug("VARIABLE: maxlogsizekb: ".$maxlogsizekb);

	if (trim($_email["mimedata"]) != "" && $size <= $maxlogsizekb)
	{
		// Do Nothing
	} else {
		$_email["mimedata"] = $_SWIFT["language"]["clearedduelimit"];
	}
	if (isset($_email["attachments"]))
	{
		unset($_email["attachments"]);
	}

	// Add the parser contents
	$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."parserlogdata` (`parserlogid`, `contents`) VALUES ('". intval($parserlogid) ."', '". $dbCore->escape(serialize($_email)) ."');");
}

/**
* Gets the Email Queue data from an array of email addresses
*/
function getEmailQueueData($recipients, &$_email)
{
	global $dbCore, $_SWIFT;

	if (count($_SWIFT["parsercatchallcache"]))
	{
		parserDebug("QUEUECHECK: Catch all rules exist");
		$catchall = true;
	} else {
		$catchall = false;
	}

	foreach ($recipients as $key=>$val)
	{
		$val = strtolower(trim($val));

		if (trim($val) != "" && isset($_SWIFT["queuecache"]["p"][$val]))
		{
			parserDebug("QUEUECHECK: Found Email Queue for: ".$val);
			$emailqueueid = intval($_SWIFT["queuecache"]["p"][$val]);

			if ($_SWIFT["queuecache"]["list"][$emailqueueid]["ticketautoresponder"] != "1")
			{
				parserDebug("QUEUECHECK: No autoresponder to dispatch");
				$_email["noautoresponder"] = true;
			}
			return $_SWIFT["queuecache"]["list"][$emailqueueid];
		} else if ($catchall == true) {
			parserDebug("QUEUECHECK: Checking Catch All rules");
			foreach ($_SWIFT["parsercatchallcache"] as $ckey=>$cval)
			{
				parserDebug("QUEUECHECK: Matching $val against ".$cval['ruleexpr']);
				if (preg_match($cval['ruleexpr'], $val)) {
					parserDebug("QUEUECHECK: Match found");
					$emailqueueid = $cval["emailqueueid"];
					if (!isset($_SWIFT["queuecache"]["list"][$emailqueueid]))
					{
						parserDebug("QUEUECHECK: No Queue Found");
						return false;
					}

					if ($_SWIFT["queuecache"]["list"][$emailqueueid]["ticketautoresponder"] != "1")
					{
						$_email["noautoresponder"] = true;
					}

					parserDebug("QUEUECHECK: Returning Email Queue ID:".$_SWIFT["queuecache"]["list"][$emailqueueid]);
					return $_SWIFT["queuecache"]["list"][$emailqueueid];
				} else {
					parserDebug("QUEUECHECK: Regular Expression didnt match");
				}
			}
		}
		
	}

	return false;
}

/**
* Processes the Content-Type and returns Mime Type and Charset.
*/
function processContentType($datastr)
{
	$returnValue=array();
	$ctypeparts = explode(';',$datastr);
	$returnValue['mimetype'] = trim($ctypeparts[0]);

	reset($ctypeparts);
	next($ctypeparts);
	while(list(,$v) = each($ctypeparts))
	{
		unset($reg);
		eregi('([^=]*)="(.*)"',$v,$reg);
		if (trim($reg[1]) && trim($reg[2])) {
			$returnValue[trim(strtolower($reg[1]))] = trim($reg[2]);
		}
	}

	return $returnValue;
}

/**
* Processes Break Lines for the given content, What it does is splits up the content into two if a break line is found and returns the splitted content. This function is useful to make sure that quoted messages do not get into the system.
*/
function processBreakLines($content)
{
	global $_SWIFT;
	parserDebug("NOTICE: Processing Breaklines");

	$breakline = &$_SWIFT["breaklinecache"];

	parserDebug("NOTICE: Breakline Total: ".count($breakline));
	if (!is_array($breakline))
	{
		parserDebug("NOTICE: No Breaklines found!");
		return $content;
	}

	foreach ($breakline as $key=>$val)
	{
		parserDebug("NOTICE: Processing Breakline: ".$val);
		$breakcontent = reversestrchr($content, $val);
		if ($breakcontent)
		{
			parserDebug("NOTICE: Breakline Triggered!");
			// Eureaka! Eureaka! Eureaka!
			return $breakcontent;
		}
	}

	return $content;
}

/**
* Reverse of strchr, returns the data from start of haystack to needle, Does not include the needle
*/
function reversestrchr($haystack, $needle)
{
	if (!$posi = strpos(strtoupper($haystack), strtoupper($needle)))
	{
		return false;
	} else {
		return substr($haystack,0,$posi);
	}
}

/**
* Gets a Ticket Mask ID or a Ticket ID From a subject. Allows a lot of combinations
*/
function parseTicketID($subject)
{
	global $_SWIFT;

	$resticketid = array();

	if (ereg("\[([A-Za-z0-9 ]{1,20}) (\#|~|!)([A-Za-z]{3}-[0-9]{5,6})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "random") {
		// First try to parse a ticket mask with a 1-20 digit company code prefixed. Example: [KAYAKO #ABC-12345]: Subject
		// 1 = Company Prefix
		// 2 = Ticket Mask ID

		$resticketid["isthirdparty"] = iif($result[2]=="~",true, false);
		$resticketid["isalert"] = iif($result[2]=="!",true, false);
		$resticketid["mask"] = $result[3];
	} else if (ereg("\[(\#|~|!)([A-Za-z]{3}-[0-9]{5,6})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "random") {
		// No luck? Now try to get a simple ticket mask then. Example: [#ABC-12345]: Subject
		// 1 = Ticket Mask ID

		$resticketid["isthirdparty"] = iif($result[1]=="~",true, false);
		$resticketid["isalert"] = iif($result[1]=="!",true, false);
		$resticketid["mask"] = $result[2];
	} else if (ereg("\[([A-Za-z]{3}-[0-9]{5,6})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "random") {
		// Give another try at ticket mask, This is added for backwards compatibility. Example: [ABC-12345]: Subject
		// 1 = Ticket Mask ID

		$resticketid["mask"] = $result[1];
	} else if (ereg("\[([A-Za-z0-9 ]{1,20}) (\#|~|!)([0-9]{5,6})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "seq") {
		// Try to get a ticket id with prefix?. Example: [KAYAKO #12345]: Subject
		// 1 = Company Prefix
		// 2 = Ticket Mask ID

		$resticketid["isthirdparty"] = iif($result[2]=="~",true, false);
		$resticketid["isalert"] = iif($result[2]=="!",true, false);
		$resticketid["id"] = $result[3];
	} else if (ereg("\[(\#|~|!)([0-9]{1,22})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "seq") {
		// Still nothing? Try to get the numeric ticket id then. Example: [#3412]: Subject
		// 1 key = 12345

		$resticketid["isthirdparty"] = iif($result[1]=="~",true, false);
		$resticketid["isalert"] = iif($result[1]=="!",true, false);
		$resticketid["id"] = $result[2];
	} else if (ereg("\[([A-Za-z0-9 ]{1,20}) (\#|~|!)([0-9]{1,22})\]", $subject, $result) && $_SWIFT["settings"]["t_eticketid"] == "seq") {
		// Still nothing? Try to get the numeric ticket id then. Example: [PREFIX #3412]: Subject
		// 1 key = 12345

		$resticketid["isthirdparty"] = iif($result[2]=="~",true, false);
		$resticketid["isalert"] = iif($result[2]=="!",true, false);
		$resticketid["id"] = $result[3];
	}

	if ($resticketid["mask"] != "" || $resticketid["id"] != "")
	{
		return $resticketid;
	} else {
		return false;
	}
}

/**
* This function cleans up the subject of its ticket id junk and returns a plain one, very useful in case a person replies to a ticket that doesnt exist.. doesnt cause the "ticket id loop" in subjects as it used to in previous versions
*/
function cleanupSubject($subject)
{
	// First see if a subject has a ticket id in it?
	if (parseTicketID($subject) && ereg("\[(.*)\]:(.*)", $subject, $result))
	{
		// Success!
		return $result[2];
	} else {
		return $subject;
	}
}

/**
* Function to strip SCRIPT tags from HTML, Taken from PHP Manual
*/
function stripScriptTag($html) {
	return ereg_replace("~<script[^>]*>.+</script[^>]*>~isU", "", $html);

/*	$pos1 = false;
	$pos2 = false;
	do {
		if ($pos1 !== false && $pos2 !== false) {
			$first = NULL;
			$second = NULL;
			if ($pos1 > 0)
			{
				$first = substr($html, 0, $pos1);
			}

			if ($pos2 < strlen($html) - 1)
			{
				$second = substr($html, $pos2);
				$html = $first . $second;
			}
		}

		preg_match("/<script[^>]*>/i", $html, $matches);
		$str1 =& $matches[0];
		preg_match("/<\/script>/i", $html, $matches);
		$str2 =& $matches[0];
		$pos1 = strpos($html, $str1);
		$pos2 = strpos($html, $str2);

		if ($pos2 !== false) {
		$pos2 += strlen($str2);
		}

	} while ($pos1 !== false && $pos2 !== false);

	return $html;*/
}

/**
* Checks whether or not the from email is banned
*/
function isParserEmailBanned($email)
{
	global $dbCore, $_SWIFT;

	if (!_is_array($_SWIFT["parserbanscache"]))
	{
		return false;
	}

	if (in_array($email, $_SWIFT["parserbanscache"]))
	{
		return true;
	}

	return false;
}
?>